package tool

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"errors"
	"fmt"
	"reflect"
	"strings"
)

func CheckoutSign(st interface{},Sign string) error {
	secret := "08818135448543989381984287403736"
	nullKey := "apom20210924sign666@!%$"
	var dataParams string
	res, err := json.Marshal(st)
	if err !=nil{
      return errors.New("序列化失败")
	}
	respMap := make(map[string]interface{})
	d := json.NewDecoder(bytes.NewReader(res))
	d.UseNumber()
	errD := d.Decode(&respMap)
	if errD != nil {
       return errors.New("反序列化失败")
	}
	//递归排序
	sortMapRes,keys := SortMapByKey(respMap)
	var builder strings.Builder
	for _, v2 := range keys {
		for k, sortVal := range sortMapRes {
				if k == v2{
					builder.WriteString(k)
					builder.WriteString("=")
					if reflect.ValueOf(sortVal).Kind() == reflect.Map {
						  maptoArr ,_:=json.Marshal(sortVal)
                          builder.WriteString(string(maptoArr))

					}else if reflect.ValueOf(sortVal).Kind() == reflect.Slice {
						maptoArr ,_:=json.Marshal(sortVal)
						builder.WriteString(string(maptoArr))
					}else {
						builder.WriteString(fmt.Sprintf("%v", sortVal))
					}
					builder.WriteString("&")
				}
		}
	}
	appString := builder.String()
	if appString == "" {
		dataParams = "signKey=" + nullKey
	}else{
		dataParams = appString[0:len(appString)-1]
	}
	//has256 加密
	key := []byte(secret)
	h := hmac.New(sha256.New, key)
	h.Write([]byte(dataParams))
	hasVal := hex.EncodeToString(h.Sum(nil))
	if hasVal != Sign {
		return errors.New("签名错误")
	}
	return  nil

}
